#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <thread>
#include "Thread.hpp"
#include <vector>
#include"Mutex.hpp"

// void* thread_test(void* args)
// {
//     char* name = (char*)args;
//     int count = 3;
//     while(count--)
//     {
//         printf("new thread tid:0x%lx\n", pthread_self());
//         //pthread_cancel(pthread_self());
//         sleep(1);
//     }
//     return (void*)10;
//     //pthread_exit(nullptr);
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, thread_test, (void*)"thread-1");
//     printf("main thread tid:0x%lx, new thread tid:0x%lx\n", pthread_self(), tid);
//     sleep(3);
//     // pthread_cancel(tid);
//     // printf("cancel success\n");
//     sleep(2);
//     void* ret;
//     int pthread_join_ret = pthread_join(tid, &ret);
//     if(pthread_join_ret == 0)
//     {
//         printf("new thread return val:%lld\n", (long long)ret);
//     }
//     printf("main thread wait, ret = %d\n", pthread_join_ret);
//     // while(1)
//     // {
//     //     std::cout << "我是主线程" << std::endl;
//     //     sleep(1);
//     // }

//     return 0;
// }

// __thread int gval = 0;

// void* thread_test(void* args)
// {
//     //pthread_detach(pthread_self());
//     char* name = static_cast<char*>(args);
//     while(1)
//     {
//         std::cout << "我是新线程:" << name;
//         printf(", gval:%d, &gval:%p\n", gval, &gval);
//         gval++;
//         sleep(1);
//     }
//     return (void*)10;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, thread_test, (void*)"thread-1");
//     while(1)
//     {
//         std::cout << "我是主线程";
//         printf(", gval:%d, &gval:%p\n", gval, &gval);
//         sleep(1);
//     }
//     // void* ret = nullptr;
//     // sleep(2);
//     // int pthread_join_ret = pthread_join(tid, &ret);
//     // std::cout << "join success, new thread ret:" << (long long)ret;
//     // std::cout << ", pthread_join ret:" << pthread_join_ret << std::endl;

//     return 0;
// }

// void test()
// {
//     while(1)
//     {
//         std::cout << "hello world" << std::endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     std::thread t(test);
//     t.join();

//     return 0;
// }

// void test()
// {
//     int count = 5;
//     while(count--)
//     {
//         std::cout << "hello world" << std::endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     // Thread t(test, "thread-1");
//     // t.Start();
//     // t.Join();
//     std::vector<Thread> v;
//     for(int i = 0; i < 5; i++)
//     {
//         std::string name = "thread-";
//         name += std::to_string(i + 1);
//         Thread t(test, name);
//         v.push_back(t);
//     }
//     for(auto& e : v)
//     {
//         e.Start();
//     }
//     for(auto& e : v)
//     {
//         e.Join();
//     }

//     return 0;
// }

// struct Data
// {   
//     char* name;
//     pthread_mutex_t* plock;
// };

// Mutex lock;

// int tickets = 1000;

// //pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

// void *routine(void *args)
// {
//     //Data *d = static_cast<Data*>(args);
//     char* name = static_cast<char*>(args);
//     while (1)
//     {
//         //pthread_mutex_lock(d->plock);
//         lock.Lock();
//         if (tickets > 0)
//         {
//             usleep(1000);
//             printf("%s线程买到票了:%d\n", name, tickets--);
//             //pthread_mutex_unlock(d->plock);
//             lock.Unlock();
//         }
//         else
//         {
//             //pthread_mutex_unlock(d->plock);
//             lock.Unlock();
//             break;
//         }
//     }
//     return (void*)0;
// }

// int main()
// {
//     // pthread_mutex_t lock;
//     // pthread_mutex_init(&lock, nullptr);
//     pthread_t t1, t2, t3, t4;
//     // Data d1({(char*)"thread-1", &lock});
//     // pthread_create(&t1, nullptr, routine, (void*)&d1);
//     // Data d2({(char*)"thread-2", &lock});
//     // pthread_create(&t2, nullptr, routine, (void*)&d2);
//     // Data d3({(char*)"thread-3", &lock});
//     // pthread_create(&t3, nullptr, routine, (void*)&d3);
//     // Data d4({(char*)"thread-4", &lock});
//     // pthread_create(&t4, nullptr, routine, (void*)&d4);
//     pthread_create(&t1, nullptr, routine, (void *)"thread-1");
//     pthread_create(&t2, nullptr, routine, (void *)"thread-2");
//     pthread_create(&t3, nullptr, routine, (void *)"thread-3");
//     pthread_create(&t4, nullptr, routine, (void *)"thread-4");
//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);
//     //pthread_mutex_destroy(&lock);

//     return 0;
// }


pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

void* routine(void* args)
{
    char* name = static_cast<char*>(args);
    while(1)
    {
        pthread_mutex_lock(&gmutex);
        pthread_cond_wait(&gcond, &gmutex);
        std::cout << name << ":hello world" << std::endl;
        pthread_mutex_unlock(&gmutex);
    }
    return (void*)0;
}

int main()
{
    pthread_t t1, t2, t3, t4;
    pthread_create(&t1, nullptr, routine, (void*)"thread-1");
    pthread_create(&t2, nullptr, routine, (void*)"thread-2");
    pthread_create(&t3, nullptr, routine, (void*)"thread-3");
    pthread_create(&t4, nullptr, routine, (void*)"thread-4");
    sleep(5);
    while(1)
    {
        //pthread_cond_signal(&gcond);
        pthread_cond_broadcast(&gcond);
        sleep(1);
    }
    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);

    return 0;
}